package org.shangda.wechat.pet.web.controller.miniapp;

import com.alibaba.fastjson.JSONObject;
import org.shangda.wechat.pet.config.MiniAppProperties;
import org.shangda.wechat.pet.dao.MemberMapper;
import org.shangda.wechat.pet.enums.EnableEnum;
import org.shangda.wechat.pet.enums.ErrorCode;
import org.shangda.wechat.pet.model.Member;
import org.shangda.wechat.pet.service.MemberService;
import org.shangda.wechat.pet.util.Constants;
import org.shangda.wechat.pet.util.WxMiniappUtil;
import com.power.common.model.CommonResult;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 小程序微信相关接口
 */
@Slf4j
@RestController
@RequestMapping("miniapp/")
public class MiniappLoginController {

    @Autowired
    private MemberService memberService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MiniAppProperties miniAppProperties;

    @Resource
    private MemberMapper memberMapper;

    /**
     * 小程序登录
     * @param code 小程序授权code
     * @return
     */
    @GetMapping("login/{code}")
    public CommonResult<LoginData> login(@PathVariable(name = "code") String code) {
        log.info("login code : {}", code);
        String appid = miniAppProperties.getAppid();
        String appSecret = miniAppProperties.getAppSecret();
        if (appid == null || appSecret == null) {
            log.error("小程序配置出错");
            return CommonResult.fail(ErrorCode.CONFIG_ERROR);
        } else {
            JSONObject res = WxMiniappUtil.jscodeToSession(appid, appSecret, code);
            log.info("miniapp login result:{}",res);
            if (res != null && !res.containsKey("errcode")) {
                // 新增用户，设置session，返回session
                String openid = res.getString("openid");
                String session_key = res.getString("session_key");
                String unionid = res.getString("unionid");
                Member member = memberService.findByOpenId(openid);
                if (member == null) {
                    member = new Member();
                    member.setOpenId(openid);
                    member.setCreatedAt(new Date());
                    member.setGender((byte) 0);
                    member.setUnionId(unionid);
                    member.setUpdatedAt(new Date());
                    member.setStatus(EnableEnum.NO.getValue());
                    memberMapper.insert(member);
                } else {
                    if (!StringUtils.isEmpty(unionid) && member.getUnionId() == null) {
                        member.setUnionId(unionid);
                        member.setUpdatedAt(new Date());
                        memberMapper.updateByPrimaryKeySelective(member);
                    }
                }
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("sessionKey", session_key);
                jsonObject.put("memberId",member.getId());
                if(!StringUtils.isEmpty(unionid)){
                    unionid = Base64.getEncoder().encodeToString(unionid.getBytes(StandardCharsets.UTF_8));
                }
                String sessionId = DigestUtils.md2Hex(openid + session_key + System.currentTimeMillis() + "");
                redisTemplate.opsForValue().set(Constants.MINIAPP_SESSION_KEY_PRE + sessionId, jsonObject);
                redisTemplate.expire(Constants.MINIAPP_SESSION_KEY_PRE + sessionId, Constants.MINIAPP_LOGIN_EXPIRE_TIME, TimeUnit.HOURS);
                LoginData loginData = new LoginData();
                loginData.setSex(member.getGender());
                loginData.setSessionId(sessionId);
                if(!StringUtils.isEmpty(unionid)){
                    loginData.setUnionId(unionid);
                }
                loginData.setOpenId(openid);
                return CommonResult.ok().setResult(loginData);
            } else {
                return CommonResult.fail(ErrorCode.LOGIN_ERROR).setResult(res);
            }
        }
    }

    /**
     * 登录后的会员信息
     */
    @Data
    public static class LoginData{

        /**
         * 请求头
         */
        private String sessionId;

        /**
         * 性别
         */
        private Byte sex;

        /**
         * unionId
         */
        private String unionId;

        /**
         * 小程序的openId
         */
        private String openId;
    }
}
